package com.weaver.drools.common.shiro.realm;

import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AccountException;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import com.weaver.drools.business.sys.user.service.IUUsrUser36Service;
import com.weaver.drools.common.entity.SysPermission;
import com.weaver.drools.common.entity.SysRole;
import com.weaver.drools.common.entity.SysUser;
import com.weaver.drools.common.entity.UUsrUser36;
import com.weaver.drools.common.redis.utils.RedisConstant;
import com.weaver.drools.common.utils.MD5Utools;
/**
 * 
*  @application name： 
*  @author: zhouxinlei
*  @time：2018年7月18日
*  @version：ver 1.1
 */
public class MyShiroRealm extends AuthorizingRealm {
	
	@Autowired
    @Lazy
	private IUUsrUser36Service user36Service;
	
	@Resource
    private RedisTemplate<String, String> stringRedisTemplate;
	/**
	 *  权限认证 
	 *  获取用户的权限信息，这是为下一步的授权做判断，获取当前用户的角色和这些角色所拥有的权限信息 
	 */
	public AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		SysUser userInfo = (SysUser) principals.getPrimaryPrincipal();
		for (SysRole role : userInfo.getRoles()) {
			authorizationInfo.addRole(role.getRoleCode());
			for (SysPermission permission : role.getPermissions()) {
				authorizationInfo.addStringPermission(permission.getPermissionUrl());
			}
		}
		return authorizationInfo;
	}

	/* 主要是用来进行身份认证的，也就是说验证用户输入的账号和密码是否正确。 */
	
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		System.out.println("=============================================【登录开始认证["+SecurityUtils.getSubject().getSession().getId()+"]】==============================================");
		UsernamePasswordToken authcToken = (UsernamePasswordToken) token;
		// 获取用户的输入的账号.
		String userName = authcToken.getUsername();
		String password = String.valueOf(authcToken.getPassword());
		//访问一次，计数一次
	    ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();
	    opsForValue.increment(RedisConstant.SHIRO_LOGIN_COUNT+userName, 1);
	    //计数大于5时，设置用户被锁定一小时
	    if(Integer.parseInt(opsForValue.get(RedisConstant.SHIRO_LOGIN_COUNT+userName))>5){
	        opsForValue.set(RedisConstant.SHIRO_IS_LOCK+userName, "LOCK");
	        stringRedisTemplate.expire(RedisConstant.SHIRO_IS_LOCK+userName, 1, TimeUnit.HOURS);
	    }
	    if ("LOCK".equals(opsForValue.get(RedisConstant.SHIRO_IS_LOCK+userName))){
	        throw new DisabledAccountException("由于密码输入错误次数大于5次，帐号已经禁止登录！");
	    }
	    Map<String, Object> map = new HashMap<>();
	    map.put("username", userName);
		String pawDES;
		try {
			pawDES = MD5Utools.MD5(password);
			map.put("password", pawDES);
			System.out.println(pawDES);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		UUsrUser36 user36 = user36Service.findUUsrUser36ByUserNamePwd(map);
		
		if (user36 == null) {
			throw new AccountException("帐号或密码不正确！");
		}else {
			opsForValue.set(RedisConstant.SHIRO_LOGIN_COUNT + userName, "0");
		}
		return new SimpleAuthenticationInfo(user36, password, getName());
	}
}